//******************************************************************************
//this code is protected by the GNU affero GPLv3
//author:Sylvain BERTRAND <sylvain.bertrand AT gmail dot com>
//                        <digital.ragnarok AT gmail dot com>
//******************************************************************************
//------------------------------------------------------------------------------
//compiler stuff
//------------------------------------------------------------------------------
#include <stdarg.h>
//------------------------------------------------------------------------------

//------------------------------------------------------------------------------
//ulinux stuff
//------------------------------------------------------------------------------
#include <ulinux/compiler_types.h>
#include <ulinux/types.h>
#include <ulinux/sysc.h>
#include <ulinux/error.h>

#include <ulinux/file.h>
#include <ulinux/stat.h>
#include <ulinux/mmap.h>

#include <ulinux/utils/ascii/ascii.h>
#include <ulinux/utils/ascii/string/string.h>
#include <ulinux/utils/ascii/string/vsprintf.h>
//------------------------------------------------------------------------------

//------------------------------------------------------------------------------
//protocol
//------------------------------------------------------------------------------
#include <wayland/display.h>
#include <wayland/callback.h>
#include <wayland/compositor.h>
#include <wayland/registry.h>
#include <wayland/shm.h>
#include <wayland/shm_pool.h>
#include <wayland/buffer.h>
#include <wayland/seat.h>
#include <wayland/output.h>
#include <wayland/keyboard.h>
#include <wayland/pointer.h>
#include <wayland/wayland.h>
//------------------------------------------------------------------------------

//------------------------------------------------------------------------------
//our private stuff
//------------------------------------------------------------------------------
#include "globals.h"
#include "objs.h"
#include "srv/shm.h"
#include "wire/wl_shm_pool.h"
#include "wire/wl_shm_pool_buffer.h"
//------------------------------------------------------------------------------

#define POOL_WIRE_VISIBLE 0x00000001//id valid
static k_u32 flgs;
static k_u32 id;
static k_i fd;
static void *start;
//we put some buffers here
static k_u32 buffer1_id;
static k_u32 buffer2_id;

#define SZ (3*K_PAGE_SZ)
#define NAME "/dev/shm/myfakepool"
void fake_shm_pool_create(void)
{
  do fd=sysc(open,3,NAME,K_O_RDWR|K_O_CREAT,K_S_IRWXUGO); while(fd==-K_EINTR);
  if(K_ISERR(fd)){
    PERR("FATAL(%d):unable to open file for fake shm pool\n",fd);
    sysc(exit_group,1,-1);
  }

  k_l r=sysc(unlink,1,NAME);
  if(K_ISERR(r)){
    PERR("FATAL(%ld):unable to unlink fake shm pool file\n",r);
    sysc(exit_group,1,-1);
  }

  do r=sysc(ftruncate,2,fd,SZ); while(r==-K_EINTR);
  if(K_ISERR(r)){
    PERR("FATAL(%ld):unable to truncate fake shm pool file to proper size\n",r);
    sysc(exit_group,1,-1);
  }

  k_l addr=sysc(mmap,6,0,SZ,K_PROT_READ|K_PROT_WRITE,K_MAP_SHARED,fd,0);
  if(K_ISERR(addr)){
    PERR("FATAL(%ld):unable to mmap the fake shm pool\n",addr);
    sysc(exit_group,1,-1);
  }
  start=(void*)addr;
  id=shm_create_pool(fd,SZ,0);
  flgs=POOL_WIRE_VISIBLE;
}

void fake_shm_pool_destroy(void)
{
  wl_shm_pool_req_destroy(id);
  sysc(munmap,2,start,SZ);
  start=0;
  flgs&=~POOL_WIRE_VISIBLE;
}

//we don't use a separate class for shm pool buffers
void fake_shm_pool_buffers_create(void)
{
  buffer1_id=objs_add(WL_BUFFER,0);//XXX:no listener for the moment
  if(buffer1_id==OBJS_MAX){
    PERRC("FATAL:unable to install the buffer1 object\n");
    sysc(exit_group,1,-1);
  }

  wl_shm_pool_req_create_buffer(id,buffer1_id,0,1,1,4,0);

  buffer2_id=objs_add(WL_BUFFER,0);//XXX:no listener for the moment
  if(buffer2_id==OBJS_MAX){
    PERRC("FATAL:unable to install the buffer2 object\n");
    sysc(exit_group,1,-1);
  }

  wl_shm_pool_req_create_buffer(id,buffer2_id,0,2,1,4*2,0);
}

void fake_shm_pool_buffers_destroy(void)
{
  wl_shm_pool_buffer_req_destroy(buffer1_id);
  wl_shm_pool_buffer_req_destroy(buffer2_id);
}
